package me.yobol.algorithm.mse.y2016;

import java.text.DecimalFormat;

/**
 *
 * @author Yobol
 */
public class MyMatrix {
    private final int row;//只被初始化一次

    private final int col;//只被初始化一次

    private final double M[][];//只被初始化一次

    private final DecimalFormat df = new DecimalFormat();
    
    public MyMatrix(double [][] a){
        this.row = a.length;
        this.col = a[0].length;
        this.M = a;
    }

    public int getRow() {
        return this.row;
    }

    public int getCol() {
        return this.col;
    }
    
    public double getElement(int i,int j){
        return this.M[i][j];
    }
    
    /**
     * 矩阵加法
     * 
     * @param B
     * @return 
     * @throws java.lang.Exception 
     */
    public MyMatrix plus(MyMatrix B) throws Exception{
        if (this.col != B.getRow()) {
            throw new Exception("不能进行矩阵加法运算");
        }
        double[][] res = new double[this.row][this.col];
        for (int i = 0; i < this.row; i++) {
            for (int j = 0; j < this.col; j++) {
                res[i][j] = this.M[i][j] + B.getElement(i, j);
            }
        }
        return new MyMatrix(res);
    }
    
    /**
     * 矩阵乘法
     * 
     * @param B
     * @return 
     * @throws java.lang.Exception 
     */
    public MyMatrix multiply(MyMatrix B) throws Exception{
        if (this.row != B.getRow() || this.col != B.getCol()) {
            throw new Exception("不能进行矩阵乘法运算");
        }
        double[][] res = new double[this.row][B.getCol()];
        for (int i = 0; i < this.row; i++) {//结果矩阵的行
            for (int j = 0; j < this.row; j++) {//结果矩阵的列
                for (int k = 0; k < this.col; k++) {
                    res[i][j] += this.M[i][k] * B.getElement(k, j);
                }
            }
        }
        return new MyMatrix(res);
    }
    
    /**
     * 矩阵转置——行列互换
     * 
     * @return 
     */
    public MyMatrix transpose(){
        double[][] res = new double[this.col][this.row];
        for (int i = 0; i < this.row; i++) {
            for (int j = 0; j < this.col; j++) {
                res[j][i] = this.M[i][j];
            }
        }
        return new MyMatrix(res);
    }
    
    /**
     * 矩阵打印
     * 起始一个空行，结束一个空行
     * 
     * @param w 每一列的宽度
     * @param d 保留的小数点位数
     */
    public void print(int w,int d){
        df.setMaximumFractionDigits(d);
        String element;
        System.out.println();
        for (int i = 0; i < this.row; i++) {
            for (int j = 0; j < this.col; j++) {
                element = df.format(this.M[i][j]);
                System.out.print(formatColumn(element, w));
            }
            System.out.println();
        }
        System.out.println();
    }
    
    
    private String formatColumn(String data,int w){
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < w; i++) {
            if (i < data.length()) {
                res.append(data.charAt(i));
            }else{
                res.append(' ');
            }
        }
        return res.toString();
    }
    
    public static void main(String[] args){
        double[][] a = {{1.1111,2.2222},{3.3333,4.4444}};
        MyMatrix A = new MyMatrix(a);
        A.print(10, 1);
        
        //double[][] b = {{1,2},{3,4},{5,6}};
        //double[][] c = {{1,2,3},{4,5,6}};
        double[][] b = {{1,2},{3,4}};
        double[][] c = {{1,2},{3,4}};
        MyMatrix B = new MyMatrix(b);
        MyMatrix C = new MyMatrix(c);
        try {
            B.plus(C).print(10, 2);
            B.multiply(C).print(10, 2);
            B.transpose().print(10, 2);
        } catch (Exception e) {
            System.out.printf(e.toString());
        }
    }
}